home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / DELPHI32 / TOOLBARS / SPLITBAR / SPLITBAR.PAS < prev    next >
Pascal/Delphi Source File  |  1996-06-24  |  8KB  |  239 lines

  1. {
  2.    WARNING! THIS CODE IS PROVIDED AS IS WITH NO GUARANTEES OF ANY KIND!
  3.    USE THIS AT YOUR OWN RISK - YOU ARE THE ONLY PERSON RESPONSIBLE FOR
  4.    ANY DAMAGE THIS CODE MAY CAUSE - YOU HAVE BEEN WARNED!
  5.  
  6.  
  7.    SplitBar component for Delphi
  8.  
  9.    Install this unit as a component and you can use whenever
  10.    you're in need of one or more panels that have to be resized.
  11.    Click on the bar and drag it around and it will resize the
  12.    underlying control.
  13.    The bar works like a panel so it has all the properties you
  14.    know from TPanel.
  15.  
  16.    Added properties are:
  17.    - SplitOrientation: Choose spHorizontal if you want to split
  18.      the underlying control horizontally and spVertical for vertical
  19.      splitting. Sorry for the confusion but I choose the identifiers
  20.      as meaningful as Borlands Cursor property: You'll have a HSplit
  21.      cursor when using spHorizontal splitting.
  22.    - MinOffset/MaxOffset: If you don't want the underlying panel to be
  23.      resized to the whole window.
  24.  
  25.    This software is free.
  26.  
  27.      (c) 01-06/1996 by Guido Schoepp
  28.    email: gus@abo.rhein-zeitung.de
  29. }
  30. unit SplitBar;
  31.  
  32. interface
  33.  
  34. uses
  35.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  36.   Forms, StdCtrls, ExtCtrls;
  37.  
  38. type
  39.   TSplitOrientation = (spHorizontal, spVertical);
  40.  
  41.   TSplitBar = class(TPanel)
  42.   private
  43.      fSplitDC : HDC;
  44.     fSplitRect : TRect;
  45.     fSplitOff,
  46.     fSplitMax,
  47.     fSplitMin : Integer;
  48.     fSplitOrg : TPoint;
  49.     fMouseIsDown : Boolean;
  50.     fOrient : TSplitOrientation;
  51.     fMaxOff,
  52.     fMinOff : Integer;
  53.     fClipRgn : HRGN;
  54.   protected
  55.     procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  56.     procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  57.     procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  58.   public
  59.        constructor Create(aOwner:TComponent); override;
  60.   published
  61.     property SplitOrientation:TSplitOrientation read fOrient write fOrient default spHorizontal;
  62.     property Cursor default crHSplit;
  63.     property MinOffset:Integer read fMinOff write fMinOff default 0;
  64.     property MaxOffset:Integer read fMaxOff write fMaxOff default 0;
  65.   end;
  66.  
  67.     procedure Register;
  68.  
  69. implementation
  70.  
  71.  
  72. constructor TSplitBar.create(aOwner:TComponent);
  73. begin
  74.     inherited Create(aOwner);
  75.    fMouseIsDown := FALSE;
  76.    fSplitDC := 0;
  77.    fOrient := spHorizontal;
  78.    Cursor := crHSplit;
  79. end;
  80.  
  81. procedure TSplitBar.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  82. var
  83.     p : TPoint;
  84.    r : TRect;
  85.    parentForm : TForm;
  86. begin
  87.     if not fMouseIsDown then
  88.    begin
  89.         fMouseIsDown := TRUE;
  90.         fSplitDC := GetWindowDC(0);
  91.  
  92.       parentForm := getParentForm(self);
  93.       r := parentForm.clientRect;
  94.  
  95.       fSplitOrg := clientToScreen(Point(x, y));
  96.       fSplitRect := clientRect;
  97.       p := clientToScreen(fSplitRect.topLeft);
  98.       fSplitRect := Rect(p.x, p.y, p.x+abs(fSplitRect.right-fSplitRect.left), p.y+abs(fSplitRect.bottom-fSplitRect.top));
  99.  
  100.       if fOrient=spHorizontal then
  101.       begin
  102.          p := parentForm.clientToScreen(r.topLeft);
  103.          fSplitMin := p.x;
  104.          p := parentForm.clientToScreen(r.bottomRight);
  105.          fSplitMax := p.x;
  106.           fSplitOff := fSplitOrg.x-fSplitRect.left;
  107.       end else
  108.       begin
  109.          p := parentForm.clientToScreen(r.topLeft);
  110.          fSplitMin := p.y;
  111.          p := parentForm.clientToScreen(r.bottomRight);
  112.          fSplitMax := p.y;
  113.  
  114.           fSplitOff := fSplitOrg.y-fSplitRect.top;
  115.       end;
  116.  
  117.       r := Application.MainForm.clientRect;
  118.       r.topLeft := Application.MainForm.clientToScreen(r.topLeft);
  119.       r.bottomRight := Application.MainForm.clientToScreen(r.bottomRight);
  120.  
  121.       fClipRgn := WinProcs.CreateRectRgnIndirect(r);
  122.  
  123.       selectClipRgn(fSplitDC, fClipRgn);
  124.       WinProcs.PatBlt(fSplitDC,
  125.                       fSplitRect.left, fSplitRect.top,
  126.                   fSplitRect.right-fSplitRect.left,
  127.                   fSplitRect.bottom-fSplitRect.top,
  128.                   PATINVERT);
  129.     end;
  130. end;
  131.  
  132. procedure TSplitBar.MouseMove(Shift: TShiftState; X, Y: Integer);
  133. var
  134.     p : TPoint;
  135. begin
  136.     if fMouseIsDown then
  137.     begin
  138.       WinProcs.PatBlt(fSplitDC,
  139.                       fSplitRect.left, fSplitRect.top,
  140.                   fSplitRect.right-fSplitRect.left,
  141.                   fSplitRect.bottom-fSplitRect.top,
  142.                   PATINVERT);
  143.  
  144.       p := clientToScreen(Point(x, y));
  145.       if fOrient=spHorizontal then
  146.       begin
  147.           fSplitRect := Rect(p.x-fSplitOff, fSplitRect.top,
  148.                                  p.x-fSplitOff+abs(fSplitRect.right-fSplitRect.left),
  149.                            fSplitRect.bottom);
  150.          if Align=alRight then
  151.          begin
  152.               if fSplitRect.Left<fSplitMin+fMinOff then
  153.                 OffsetRect(fSplitRect, fSplitMin+fMinOff-fSplitRect.left, 0);
  154.              if fSplitRect.Right>fSplitMax-fMaxOff then
  155.                 OffsetRect(fSplitRect, fSplitMax-fMaxOff-fSplitRect.right, 0);
  156.          end else
  157.          if Align=alLeft then
  158.          begin
  159.               if fSplitRect.Left<fSplitMin+fMaxOff then
  160.                 OffsetRect(fSplitRect, fSplitMin+fMaxOff-fSplitRect.left, 0);
  161.              if fSplitRect.Right>fSplitMax-fMinOff then
  162.                 OffsetRect(fSplitRect, fSplitMax-fMinOff-fSplitRect.right, 0);
  163.          end;
  164.         end else
  165.       begin
  166.           fSplitRect := Rect(fSplitRect.left, p.y-fSplitOff,
  167.                              fSplitRect.right, p.y-fSplitOff+abs(fSplitRect.bottom-fSplitRect.top));
  168.  
  169.          if Align=alBottom then
  170.          begin
  171.             if fSplitRect.top<fSplitMin+fMinOff then
  172.                OffsetRect(fSplitRect, 0, fSplitMin+fMinOff-fSplitRect.top);
  173.             if fSplitRect.bottom>fSplitMax-fMaxOff then
  174.                OffsetRect(fSplitRect, 0, fSplitMax-fMaxOff-fSplitRect.bottom);
  175.          end else
  176.          if Align=alTop then
  177.          begin
  178.             if fSplitRect.top<fSplitMin+fMaxOff then
  179.                OffsetRect(fSplitRect, 0, fSplitMin+fMaxOff-fSplitRect.top);
  180.             if fSplitRect.bottom>fSplitMax-fMinOff then
  181.                OffsetRect(fSplitRect, 0, fSplitMax-fMinOff-fSplitRect.bottom);
  182.          end;
  183.       end;
  184.       WinProcs.PatBlt(fSplitDC,
  185.                       fSplitRect.left, fSplitRect.top,
  186.                   fSplitRect.right-fSplitRect.left,
  187.                   fSplitRect.bottom-fSplitRect.top,
  188.                   PATINVERT);
  189.    end;
  190. end;
  191.  
  192. procedure TSplitBar.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  193. var
  194.    off : Integer;
  195. begin
  196.     if fMouseIsDown then
  197.    begin
  198.       WinProcs.PatBlt(fSplitDC,
  199.                       fSplitRect.left, fSplitRect.top,
  200.                   fSplitRect.right-fSplitRect.left,
  201.                   fSplitRect.bottom-fSplitRect.top,
  202.                   PATINVERT);
  203.  
  204.       if fOrient=spHorizontal then
  205.       begin
  206.           off := fSplitOrg.x-(fSplitOff+fSplitRect.left);
  207.           if Align = alLeft then
  208.               parent.width := parent.width + off
  209.           else if Align = alRight then
  210.               parent.width := parent.width - off;
  211.       end else
  212.       begin
  213.           off := fSplitOrg.y-(fSplitOff+fSplitRect.top);
  214.           if Align = alTop then
  215.               parent.height := parent.height + off
  216.           else if Align = alBottom then
  217.               parent.height := parent.height - off;
  218.       end;
  219.  
  220.         DeleteObject(fClipRgn);
  221.       fClipRgn := 0;
  222.  
  223.       if (fSplitDC<>0) then
  224.           ReleaseDC(0, fSplitDC);
  225.       fSplitDC := 0;
  226.  
  227.        fMouseIsDown := FALSE;
  228.    end;
  229. end;
  230.  
  231.  
  232. procedure Register;
  233. begin
  234.   RegisterComponents('test', [TSplitBar]);
  235. end;
  236.  
  237.  
  238. end.
  239.